package com.kehutong.department.controller;

import java.io.InputStream;
import java.util.*;

import com.kehutong.common.interceptor.TrasIntercepter;
import com.kehutong.common.permission.DataPermissionQuery;
import com.kehutong.common.permission.UserLoginInfo;
import com.kehutong.department.service.DepartmentService;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.coraframework.authz.HasPermission;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.Pool;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import com.kehutong.common.ExcelUtil;
import com.kehutong.common.entity.Root;
import com.kehutong.common.entity.TreeUtil;
import com.kehutong.common.urlconfig.FileUrlConfig;
import com.kehutong.common.util.Token;
import com.kehutong.department.entity.Department;

@MvcAction
@ReqMapping("/admin/basic/department")
public class DepartmentController {
	
	@Inject
	private JdbcSession jdbcSession;
	@Inject
	private FileUrlConfig fileUrlConfig;
	@Inject
	private DepartmentService departmentService;
	
	@HasPermission("department:list:view")
    @ReqMapping("/tree")
    public Object tree(Token token, JSONObject jsonObject) {
		FindArray<Department> find = jdbcSession.findArray(Department.class)
				.eq("deleted", false)
				.like(jsonObject, "departments")
				.order("sort", "desc");

		DataPermissionQuery.setManageDepartmentNoDataSql(find, null);

		List<Department> departmentList = find.exe();

		Map<String, Department> treeMap = TreeUtil.asMapById(departmentList);
		Set<String> departments = new HashSet<>(token.getDepartments());

		UserLoginInfo userLoginInfo = DataPermissionQuery.getUserInfo(null);
		if(Objects.nonNull(userLoginInfo.getManageDepartmentNo())){
			departments.addAll(userLoginInfo.getManageDepartmentNo());
		}

		for (String id : departments) {
			Department dep = Pool.get(Department.class, id);
			if (dep != null) {
				treeMap.put(dep.getId(), dep);
			}
		}

		Department root = TreeUtil.organizeAsTree(treeMap, false);
		if (Objects.nonNull(root)) {
			return root;
		}

		List<Department> fisrtChildList = new ArrayList<>();
		for (String id : departments) {
			Department dep = treeMap.get(id);
			if (dep != null) {
				fisrtChildList.add(dep);
			}
		}

		root = Pool.newInstance(Department.class, "a");
		root.setName(token.getCompanyName());
		root.setChildList(fisrtChildList);

		return root;
    }

	@ReqMapping("/list")
	public Object list(Token token, JSONObject jsonObject) {
		Boolean isAll = jsonObject.getBoolean("isAll");

		FindPage<Department> find = jdbcSession.findPage(Department.class)
				.eq(jsonObject, "parent_id")
				.like(jsonObject, "parent_ids","name")
				.in(jsonObject, "id")
				.order("sort", "desc");
		find.page(jsonObject);

		if(!isAll){
			find.eq("deleted", false);
		}

		return find.exe();
	}

	@HasPermission("department:list:view")
	@ReqMapping("/getEmployeeTransfer")
	public Object getEmployeeTransfer (Token token, JSONObject jsonObject) throws Exception {
		JSONArray data = new JSONArray(2);

		Department department = Pool.get(Department.class, jsonObject.getString("parent_id"));

		List<String> departmentIds = new ArrayList<>();
		departmentIds.add(department.getId());

		JSONArray employees = departmentService.getEmployees(departmentIds);

		List<JSONObject> array = new ArrayList<>();
		employees.forEach(item-> {
			JSONObject employee = (JSONObject) item;
			if(employee.getJSONArray("department").contains(department.getId())){
				array.add(departmentService.employee2JSONObject(department.getId(), employee));
			}
		});

		JSONObject root = departmentService.department2JSONObject(department);
		data.add(root);
		data.add(array);
		return Result.success(data);
	}

	@HasPermission("department:list:view")
	@ReqMapping("/getDepartmentTransfer")
	public Object getDepartmentTransfer (Token token, JSONObject jsonObject) throws Exception {
		JSONArray data = new JSONArray(2);

		Department department = Pool.get(Department.class, jsonObject.getString("parent_id"));
		FindArray<Department> find = jdbcSession.findArray(Department.class)
				.eq("parent_id", department.getId())
				.eq("deleted", false);

		List<Department> departments = find.exe();

		List<String> departmentIds = new ArrayList<>();
		departments.forEach(item->{
			departmentIds.add(item.getId());
		});
		departmentIds.add(department.getId());

		List<JSONObject> array = new ArrayList<>();
		departments.forEach(item->{
			array.add(departmentService.department2JSONObject(item));
		});

		JSONObject root = departmentService.department2JSONObject(department);
		data.add(root);
		data.add(array);
		return Result.success(data);
	}

	@HasPermission("department:list:view")
	@ReqMapping("/getDepartment")
	public Object getDepartmentEmployee (Token token, JSONObject jsonObject) throws Exception {
		String parent_id = jsonObject.getString("parent_id");
		if(Objects.nonEmpty(parent_id)){
			return departmentService.doGetDepartmentEmployee(jsonObject);
		}else{
			return departmentService.doGetDepartmentEmployeeCreateRoot(token);
		}
	}

	@HasPermission("wwout:department:edit")
	@ReqMapping("/readFile")
	public Object readFile(String fileId) throws Exception {
		InputStream is = fileUrlConfig.download(fileId);
		Workbook wb = WorkbookFactory.create(is);
		Sheet sheet = wb.getSheetAt(0);

		for (int rIndex = sheet.getFirstRowNum(); rIndex <= sheet.getLastRowNum(); rIndex++) {
			Row row = sheet.getRow(rIndex);
			String id = ExcelUtil.getCellValue(row.getCell(0));
			Department department = Pool.get(Department.class, id);
			if (Objects.nonNull(department)) {
				String name = ExcelUtil.getCellValue(row.getCell(1));
				department.setName(name);
				jdbcSession.updateById(department);
			}
		}

		return Result.success();
	}

	@ReqMapping("/updateName")
	public Object updateName(JSONObject jsonObject) throws Exception {
		JSONArray jsonArray = jsonObject.getJSONArray("departments");
		List<Department> departmentList = new ArrayList<>();
		for (int i = 0; i < jsonArray.size(); i++) {
			JSONObject each = (JSONObject) jsonArray.get(i);
			Department department = Pool.get(Department.class, each.getString("id"));
			if (Objects.nonNull(department) && !Objects.equal(department.getName(), each.getString("name"))) {
				department.setName(each.getString("name"));
				departmentList.add(department);
			}
		}
		if (departmentList.size() > 0) {
			jdbcSession.updateById(departmentList);
		}
		return Result.success();
	}

    @HasPermission("department:list:view")
    @ReqMapping("/getDepartmentEmpTransfer")
    public Object getDepartmentEmpTransfer (Token token, JSONObject jsonObject) throws Exception {
        return departmentService.doGetDepartmentEmployee(jsonObject);
    }

	@ReqMapping("/departInfoCount")
	public Object departInfoCount(Token token) throws Exception {
		List<Department> departments = jdbcSession.findArray(Department.class)
				.eq("deleted", false)
				.exe();

		JSONArray employees = departmentService.getEmployees(null);

		JSONArray communitys = departmentService.getCommunityByIds();

		JSONArray houses = departmentService.getHouses();

		JSONObject result = new JSONObject();
		result.put("departCount", departments.size());
		result.put("employeeCount", employees.size());
		result.put("communityCount", communitys.size());
		result.put("houseCount", houses.size());

		return result;
	}
	
    @HasPermission("department:list:view")
    @ReqMapping("/get")
    public Object get(Department item) {
    	return item;
    }
    
    @TrasIntercepter("/wwin/department/wwin/create")
    @Bean(newInstance=true, copy=true)
    @HasPermission("department:form:save")
    @ReqMapping("/save")
    public Object save(Department item) throws Exception {
		if (Objects.isEmpty(item.getPid())) {
			item.setId(Root.ROOT_ID);
    	}

		// 增加校验当前层级下不允许有相同的部门名称
		Department department = jdbcSession.findOne(Department.class)
				.eq("name", item.getName())
				.eq("parent_id", item.getParent_id())
				.eq("deleted", false)
				.exe(false);

		if(Objects.nonNull(department)){
			return Result.error(0, "当前部门下不允许有相同的部门名称");
		}

        //修改员工的主管部门信息
		departmentService.updateDutyDepartment(item);
    	
    	jdbcSession.insert(item);
    	return Result.success(item);
    }
    
    @TrasIntercepter("/wwin/department/wwin/update")
    @Bean(newInstance=false, copy=true)
    @HasPermission("department:form:update")
    @ReqMapping("/update")
    public Object update(Department item) throws Exception {

		// 增加校验当前层级下不允许有相同的部门名称
		Department department = jdbcSession.findOne(Department.class)
				.eq("name", item.getName())
				.eq("parent_id", item.getParent_id())
				.eq("deleted", false)
				.noEq("id", item.getId())
				.exe(false);

		if(Objects.nonNull(department)){
			return Result.error(0, "当前部门下不允许有相同的部门名称");
		}

        //修改员工的主管部门信息
		departmentService.updateDutyDepartment(item);

		jdbcSession.updateById(item);

		// 重新设置所有子节点的 父节点信息
		departmentService.setParentIds(item);

    	return Result.success(item);
    }

//    @TrasIntercepter("/kht-bin/wwout/change_department/delete")
    @TrasIntercepter("/wwin/department/wwin/delete")
    @HasPermission("department:form:delete")
    @ReqMapping("/delete")
    public Object delete(Department item) throws Exception {

		JSONArray array = departmentService.getEmployees(Arrays.asList(item.getId()));
		if(Objects.nonEmpty(array)){
			return Result.error(0, "需先删除该部门下的员工，再删除该部门！");
		}

    	if (Objects.nonNull(item)) {
    		item.setDeleted(true);
    		jdbcSession.updateById(item);
    	}
    	
    	return Result.success();
    }

	@HasPermission("department:form:delete")
	@ReqMapping("/batch/delete")
	public Object batchDelete(JSONObject jsonObject) throws Exception {
		JSONArray ids = jsonObject.getJSONArray("ids");
		List<String> departments = JSONObject.parseArray(ids.toString(),String.class);
		JSONArray array = departmentService.getEmployees(departments);

		if(Objects.nonEmpty(array)){
			return Result.error(0, "需先删除部门下的员工，再删除该部门！");
		}

		for (String id: departments) {
			Department entity = Pool.get(Department.class, id);

			if (Objects.nonNull(entity)) {
				entity.setDeleted(true);
				jdbcSession.updateById(entity);
			}
		}

		return Result.success();
	}

	@HasPermission("department:form:update")
	@ReqMapping("/updateSort")
	public Object updateSort(JSONObject jsonObject) {
		JSONArray array = jsonObject.getJSONArray("data");
		for (int i = 0; i < array.size(); i ++) {
			JSONObject json = array.getJSONObject(i);
			Department department = Pool.get(Department.class, json.getString("id"));
			department.setSort(json.getInteger("sort"));
			jdbcSession.updateById(department);
		}
		return Result.success();
	}

    @HasPermission("department:form:update")
    @ReqMapping("/sort")
    public Object order(Department item, Integer sort) throws Exception {
    	item.setSort(sort);
		jdbcSession.updateById(item);
		
    	return Result.success();
    }
}
